/**
 * created by dt 2025-05-26
 * 属性修改器 - C#版本
 */

using System;
using System.Collections.Generic;
using UnityEngine;

namespace DLib.Attribute
{
    /// <summary>
    /// 属性修饰器类型
    /// </summary>
    public enum ModifierType
    {
        Flat = 0,           // 绝对值
        Percentage = 1,     // 百分比（万分比）
        Based = 2,          // 基于其他属性的百分比
    }

    /// <summary>
    /// 属性修饰器优先级
    /// </summary>
    public enum ModifierPriority
    {
        Base = 0,           // 基础属性加成
        Equipment = 1,      // 装备加成
        Buff = 2,           // 状态效果加成
        Special = 3,        // 特殊效果加成
    }

    /// <summary>
    /// 属性修饰器
    /// </summary>
    [Serializable]
    public class AttributeModifier
    {
        // 定义万分比转换常量
        public static readonly int PERCENTAGE_SCALE = 10000; // 万分比基数

        public ModifierType Type { get; }
        public int Value { get; } // 对于百分比类型，value直接存储万分比整数值
        public ModifierPriority Priority { get; }
        public int? BasedOnAttribute { get; }

        public AttributeModifier(ModifierType type, int value, ModifierPriority priority, int? basedOnAttribute = null)
        {
            Type = type;
            Value = value;
            Priority = priority;
            BasedOnAttribute = basedOnAttribute;
        }

        /// <summary>
        /// 工具方法：将百分比转换为万分比整数值
        /// </summary>
        public static int ToPercentageValue(float percentage)
        {
            return Mathf.RoundToInt(percentage * PERCENTAGE_SCALE);
        }

        /// <summary>
        /// 工具方法：将万分比整数值转换为百分比
        /// </summary>
        public static float FromPercentageValue(int value)
        {
            return (float)value / PERCENTAGE_SCALE;
        }

        /// <summary>
        /// 创建百分比修饰器
        /// </summary>
        public static AttributeModifier CreatePercentage(float percentage, ModifierPriority priority = ModifierPriority.Buff)
        {
            return new AttributeModifier(ModifierType.Percentage, ToPercentageValue(percentage), priority);
        }

        /// <summary>
        /// 创建绝对值修饰器
        /// </summary>
        public static AttributeModifier CreateFlat(int value, ModifierPriority priority = ModifierPriority.Buff)
        {
            return new AttributeModifier(ModifierType.Flat, value, priority);
        }

        /// <summary>
        /// 创建基于其他属性的修饰器
        /// </summary>
        public static AttributeModifier CreateBased(int basedOnAttribute, float percentage, ModifierPriority priority = ModifierPriority.Buff)
        {
            return new AttributeModifier(ModifierType.Based, ToPercentageValue(percentage), priority, basedOnAttribute);
        }
    }

    /// <summary>
    /// 属性系统
    /// </summary>
    [Serializable]
    public class Attributes
    {
        // 基础值存储
        private Dictionary<int, int> baseValues = new Dictionary<int, int>();
        
        // 当前值缓存
        private Dictionary<int, int> currentValues = new Dictionary<int, int>();
        
        // 属性依赖关系
        private Dictionary<int, HashSet<int>> dependencies = new Dictionary<int, HashSet<int>>();
        
        // 脏标记，用于延迟计算
        private HashSet<int> dirtyFlags = new HashSet<int>();
        
        // 修饰器存储：属性ID -> 优先级 -> 修饰器列表
        private Dictionary<int, Dictionary<ModifierPriority, List<AttributeModifier>>> modifiers = 
            new Dictionary<int, Dictionary<ModifierPriority, List<AttributeModifier>>>();

        // 事件系统
        public event Action<int, int, int> OnAttributeChanged; // 属性ID, 旧值, 新值

        #region 基础操作

        /// <summary>
        /// 设置基础值
        /// </summary>
        public void SetBaseValue(int type, int value)
        {
            int oldValue = GetCurrentValue(type);
            baseValues[type] = value;
            MarkDirty(type);
            
            int newValue = GetCurrentValue(type);
            if (oldValue != newValue)
            {
                OnAttributeChanged?.Invoke(type, oldValue, newValue);
            }
        }

        /// <summary>
        /// 获取基础值
        /// </summary>
        public int GetBaseValue(int type)
        {
            return baseValues.TryGetValue(type, out int value) ? value : 0;
        }

        /// <summary>
        /// 获取当前值（包含所有修饰器效果）
        /// </summary>
        public int GetCurrentValue(int type)
        {
            if (dirtyFlags.Contains(type))
            {
                RecalculateValue(type);
            }
            return currentValues.TryGetValue(type, out int value) ? value : 0;
        }

        /// <summary>
        /// 直接设置当前值（不触发重新计算）
        /// </summary>
        public void SetCurrentValue(int type, int value)
        {
            int oldValue = GetCurrentValue(type);
            currentValues[type] = value;
            dirtyFlags.Remove(type); // 清除脏标记
            
            if (oldValue != value)
            {
                OnAttributeChanged?.Invoke(type, oldValue, value);
            }
        }

        /// <summary>
        /// 同时设置基础和当前值
        /// </summary>
        public void SetCurrentValueWithBase(int type, int value)
        {
            SetBaseValue(type, value);
            SetCurrentValue(type, value);
        }

        #endregion

        #region 修饰器管理

        /// <summary>
        /// 添加修饰器
        /// </summary>
        public void AddModifier(int type, AttributeModifier modifier)
        {
            if (!modifiers.ContainsKey(type))
            {
                modifiers[type] = new Dictionary<ModifierPriority, List<AttributeModifier>>();
            }

            var typeModifiers = modifiers[type];
            if (!typeModifiers.ContainsKey(modifier.Priority))
            {
                typeModifiers[modifier.Priority] = new List<AttributeModifier>();
            }

            typeModifiers[modifier.Priority].Add(modifier);
            MarkDirty(type);
        }

        /// <summary>
        /// 添加百分比修饰器
        /// </summary>
        public AttributeModifier AddPercentageModifier(int attrType, float percentage, ModifierPriority priority = ModifierPriority.Buff)
        {
            var modifier = AttributeModifier.CreatePercentage(percentage, priority);
            AddModifier(attrType, modifier);
            return modifier;
        }

        /// <summary>
        /// 添加绝对值修饰器
        /// </summary>
        public AttributeModifier AddFlatModifier(int attrType, int value, ModifierPriority priority = ModifierPriority.Buff)
        {
            var modifier = AttributeModifier.CreateFlat(value, priority);
            AddModifier(attrType, modifier);
            return modifier;
        }

        /// <summary>
        /// 添加基于其他属性的修饰器
        /// </summary>
        public AttributeModifier AddBasedModifier(int attrType, int basedOnAttribute, float percentage, ModifierPriority priority = ModifierPriority.Buff)
        {
            var modifier = AttributeModifier.CreateBased(basedOnAttribute, percentage, priority);
            AddModifier(attrType, modifier);
            return modifier;
        }

        /// <summary>
        /// 移除修饰器
        /// </summary>
        public void RemoveModifier(int type, AttributeModifier modifier)
        {
            if (modifiers.TryGetValue(type, out var typeModifiers) &&
                typeModifiers.TryGetValue(modifier.Priority, out var priorityModifiers))
            {
                if (priorityModifiers.Remove(modifier))
                {
                    if (priorityModifiers.Count == 0)
                    {
                        typeModifiers.Remove(modifier.Priority);
                    }
                    if (typeModifiers.Count == 0)
                    {
                        modifiers.Remove(type);
                    }
                    MarkDirty(type);
                }
            }
        }

        /// <summary>
        /// 获取指定属性的所有修饰器
        /// </summary>
        public List<AttributeModifier> GetModifiers(int type)
        {
            var allModifiers = new List<AttributeModifier>();
            if (modifiers.TryGetValue(type, out var typeModifiers))
            {
                foreach (var priorityModifiers in typeModifiers.Values)
                {
                    allModifiers.AddRange(priorityModifiers);
                }
            }
            return allModifiers;
        }

        /// <summary>
        /// 获取指定属性和优先级的修饰器
        /// </summary>
        public List<AttributeModifier> GetModifiersByPriority(int type, ModifierPriority priority)
        {
            if (modifiers.TryGetValue(type, out var typeModifiers) &&
                typeModifiers.TryGetValue(priority, out var priorityModifiers))
            {
                return new List<AttributeModifier>(priorityModifiers);
            }
            return new List<AttributeModifier>();
        }

        /// <summary>
        /// 清除指定属性的所有修饰器
        /// </summary>
        public void ClearModifiers(int type)
        {
            if (modifiers.Remove(type))
            {
                MarkDirty(type);
            }
        }

        /// <summary>
        /// 清除指定属性和优先级的修饰器
        /// </summary>
        public void ClearModifiersByPriority(int type, ModifierPriority priority)
        {
            if (modifiers.TryGetValue(type, out var typeModifiers) && typeModifiers.Remove(priority))
            {
                if (typeModifiers.Count == 0)
                {
                    modifiers.Remove(type);
                }
                MarkDirty(type);
            }
        }

        #endregion

        #region 依赖关系管理

        /// <summary>
        /// 添加属性依赖关系
        /// </summary>
        public void AddDependency(int source, int target)
        {
            if (!dependencies.ContainsKey(source))
            {
                dependencies[source] = new HashSet<int>();
            }
            dependencies[source].Add(target);
        }

        /// <summary>
        /// 移除属性依赖关系
        /// </summary>
        public void RemoveDependency(int source, int target)
        {
            if (dependencies.TryGetValue(source, out var deps))
            {
                deps.Remove(target);
                if (deps.Count == 0)
                {
                    dependencies.Remove(source);
                }
            }
        }

        /// <summary>
        /// 获取指定属性的依赖
        /// </summary>
        public HashSet<int> GetDependencies(int source)
        {
            return dependencies.TryGetValue(source, out var deps) ? new HashSet<int>(deps) : new HashSet<int>();
        }

        /// <summary>
        /// 检查是否存在依赖关系
        /// </summary>
        public bool HasDependency(int source, int target)
        {
            return dependencies.TryGetValue(source, out var deps) && deps.Contains(target);
        }

        #endregion

        #region 内部计算

        /// <summary>
        /// 标记属性为脏状态
        /// </summary>
        private void MarkDirty(int type)
        {
            if (dirtyFlags.Contains(type)) return;
            
            dirtyFlags.Add(type);
            
            // 标记依赖此属性的其他属性也为脏
            if (dependencies.TryGetValue(type, out var deps))
            {
                foreach (var dep in deps)
                {
                    MarkDirty(dep);
                }
            }
        }

        /// <summary>
        /// 重新计算属性值
        /// </summary>
        private void RecalculateValue(int type)
        {
            // 如果没有base值，使用当前值作为base值
            int baseValue = baseValues.TryGetValue(type, out int baseVal) ? baseVal : 
                           (currentValues.TryGetValue(type, out int currentVal) ? currentVal : 0);
            
            int finalValue = baseValue;

            // 按优先级顺序处理修饰器
            if (modifiers.TryGetValue(type, out var typeModifiers))
            {
                // 按优先级排序处理
                var sortedPriorities = new List<ModifierPriority>(typeModifiers.Keys);
                sortedPriorities.Sort();

                foreach (var priority in sortedPriorities)
                {
                    var modifiers = typeModifiers[priority];
                    if (modifiers == null || modifiers.Count == 0) continue;

                    int totalFlat = 0;
                    int totalPercentage = 0;

                    // 收集当前优先级的所有修饰器效果
                    foreach (var modifier in modifiers)
                    {
                        switch (modifier.Type)
                        {
                            case ModifierType.Flat:
                                totalFlat += modifier.Value;
                                break;
                            case ModifierType.Percentage:
                                // value已经是万分比整数值，直接累加
                                totalPercentage += modifier.Value;
                                break;
                            case ModifierType.Based:
                                if (modifier.BasedOnAttribute.HasValue)
                                {
                                    int basedOnValue = GetCurrentValue(modifier.BasedOnAttribute.Value);
                                    // 将万分比转换为实际百分比后再计算，并确保整数结果
                                    totalFlat += Mathf.RoundToInt(basedOnValue * (float)modifier.Value / AttributeModifier.PERCENTAGE_SCALE);
                                }
                                break;
                        }
                    }

                    // 应用当前优先级的效果
                    // 先计算百分比加成，确保整数结果
                    float percentageMultiplier = 1f + (float)totalPercentage / AttributeModifier.PERCENTAGE_SCALE;
                    // 应用加成并确保最终结果为整数
                    finalValue = Mathf.RoundToInt((finalValue + totalFlat) * percentageMultiplier);
                }
            }

            currentValues[type] = finalValue;
            dirtyFlags.Remove(type);
        }

        #endregion

        #region 工具方法

        /// <summary>
        /// 复制属性到目标对象
        /// </summary>
        public void CopyTo(Attributes target, bool copyDependencies = false, bool copyModifiers = false)
        {
            target.Reset();

            foreach (var kvp in baseValues)
            {
                target.baseValues[kvp.Key] = kvp.Value;
            }
            
            foreach (var kvp in currentValues)
            {
                target.currentValues[kvp.Key] = kvp.Value;
            }

            if (copyDependencies)
            {
                foreach (var kvp in dependencies)
                {
                    target.dependencies[kvp.Key] = new HashSet<int>(kvp.Value);
                }
            }

            if (copyModifiers)
            {
                foreach (var kvp in modifiers)
                {
                    var newTypeModifiers = new Dictionary<ModifierPriority, List<AttributeModifier>>();
                    foreach (var priorityKvp in kvp.Value)
                    {
                        newTypeModifiers[priorityKvp.Key] = new List<AttributeModifier>(priorityKvp.Value);
                    }
                    target.modifiers[kvp.Key] = newTypeModifiers;
                }
            }
        }

        /// <summary>
        /// 重置所有属性
        /// </summary>
        public void Reset()
        {
            baseValues.Clear();
            currentValues.Clear();
            dependencies.Clear();
            dirtyFlags.Clear();
            modifiers.Clear();
        }

        /// <summary>
        /// 获取所有属性ID
        /// </summary>
        public HashSet<int> GetAllAttributeIds()
        {
            var ids = new HashSet<int>();
            foreach (var id in baseValues.Keys) ids.Add(id);
            foreach (var id in currentValues.Keys) ids.Add(id);
            foreach (var id in modifiers.Keys) ids.Add(id);
            return ids;
        }

        /// <summary>
        /// 检查属性是否存在
        /// </summary>
        public bool HasAttribute(int type)
        {
            return baseValues.ContainsKey(type) || currentValues.ContainsKey(type) || modifiers.ContainsKey(type);
        }

        #endregion
    }
} 